<?php
	include('config.inc');
	
	//$allowed = "/.*/";
	//echo $allowed;

    function getAbsolutePath($url, $relative_url){
    	/**
    	 * Takes a URL, and retrieves the path minus the file.
    	 * Probably not the most efficient way to do this
    	 * @param string $url URL to retrieve the path from
    	 * @param integer $relative_url url we have read in; need to check for levels up (e.g., '../../..')
    	 * @return string
    	 */
    	
    	//if the relative_url starts out '/', it comes from the root and we should just return the base host
    	if($relative_url[0] == '/')
    		return getHost($url);

    	//check how many levels up we should go, if any
    	$count = substr_count($relative_url, '../');
    	
    	//remove the http:// part (and store it, in case its something else, like https)
    	$protocol = $pieces = explode('//', $url);
    	$url 	  = $protocol[1];
    	$protocol = $protocol[0] . "//";

    	$pieces = explode('/', $url);

    	$ret = '';
	
    	//if there is only one $piece, then the for-loop below won't work right
    	if(count($pieces) == 1)
    		return $protocol . $pieces[0] . "/";
    	
    	for($i = 0; $i < count($pieces) - ($count + 1); $i++){
    		$ret .= $pieces[$i] . "/";
    	}
    	return $protocol .= $ret;
    }
    
    function getHost($url){
    	/**
    	 * Takes a URL and returns the host
    	 * @param string $url the URL to retrieve the host from
    	 * @return string
    	 */
    	
    	//store the protocol
    	$pieces = explode('//', $url);
    	$path     = $pieces[1];
    	$protocol = $pieces[0] . "//";
    	
    	//get the host
    	$host = explode('/', $path);
    	
    	return $protocol . $host[0];
    }
    
    function validText($text, $ignore){
    	/**
    	 * Returns true if $text is not found in $ignore 
    	 * $ignore is a comma delimitted list of words to be ignored
    	 * @param string $text a text string we want to test
    	 * @param string $a list of words that, if found, should return false
    	 * @return boolean
    	 */
    	
    	$ignore = explode(',', $ignore);
    	foreach($ignore as $i){
    		//echo "Checking-$text-and-$i-(" . strstr($text, $i) . ")<br>";
    		if(!strstr(trim($text), trim($i)) === FALSE){
    			return false;
    		}
    	}
    	
    	return true;
    }
    
    function testPageAllowed($page){
    	//returns true if page is allowed; only use after page is denied
    	//$allowed = "/http:\/\/ittimes.ucdavis.edu$/, /http:\/\/clm.ucdavis.edu$/, /http:\/\/clm.ucdavis.edu\/rooms.*$/,
    	///http:\/\/clm.ucdavis.edu\/people.*$/,/http:\/\/clm.ucdavis.edu\/jobs.*$/";
    	global $allowed;
    	$tmp = explode(",", $allowed);
    	
    	foreach($tmp as $a)
    	//echo $a . " " . $page . "<br>";
    		if(preg_match($a, $page)){
    			return true;
    		}
    			
    	return false;
    }
    
    function linkResolver($currentPage, $relativeURL){
		/**
		 * Possible cases:
		 * 
		 * ./relative = URL of the current page, minus the last element, plus relativeURL
		 * relative   = URL of the current page, minus the last element, plus relativeURL
		 * ../relative= URL of the current page, up 1 or more levels,    plus relativeURL
		 * ..         = URL of the current page, up 1 level,             plus relativeURL
		 * /relative  = Root URL, plus relative URL
		 * http://rel = Relative URL
		 * 
		 */
		
		/**
		 * Takes the current page and generates the absolute URL for the relativeURL
		 * 
		 * @param string $currentPage URL of the current page we're on
		 * @param string $relativeURL URL of a link on $currentPage
		 * @return string The absolute link version of the relative link
		 */
		
		$localDebug = 0;

		//never follow URLs containing the following; just return $currentPage
		//$forbiddenWords = "javascript, mailto, .png, .bmp, .pdf, .jpg, .xls, .doc, .gif, .mov, .mpg, .wmv, .ppt, ittimes.ucdavis.edu, clm.ucdavis.edu, scg.ucdavis.edu/bitsbytes, cr.ucdavis.edu/forms, technews.ucdavis.edu/, etpartners.ucdavis.edu/binder/, iet.ucdavis.edu/glance/, graphviz.org/webdot, graphviz.org/bug, graphviz.org/pub, graphviz.org/Download, graphviz.org/Gallery, graphviz.org/Doc, noc.ucdavis.edu/wireless/summary, email.ucdavis.edu/sendmail, xxxxxxxxxxxxxxxxxxx";
		global $forbiddenWords;
		$tmp = explode(", ", $forbiddenWords);
		foreach($tmp as $t){
			//echo "Checking $t<br>";
			if(strstr($currentPage, $t) or (!testPageAllowed($currentPage) and strstr($currentPage, $t)))		//if the link is on the black list, or the current page is banned and is not on the white list
				return "forbidden";												//then return forbidden
		}

		//Test if 'relative URL' is absolute
		//$tmp = explode("//", $relativeURL);
		if(strstr($relativeURL, "http")){
			return $relativeURL;
		}
		
		//very strange case where 'URL' starts with a question mark
		//e.g., ?q=search or something like that
		if($relativeURL[0] == "?"){
			$currentPage = explode("?", $currentPage);
				return $currentPage[0] . $relativeURL;
			
		}
			
		//case when relative begins with ./ 
		if(
			($relativeURL[0] == "." and $relativeURL[1] == "/")
		){
			/*$relativeURL = explode("./", $relativeURL);
			
			if(isset($relativeURL[1]))
				$relativeURL[0] = $relativeURL[1];*/
				
			//strip out any ./ that is present
			$relativeURL = str_replace("./", "", $relativeURL);
				
			if(!preg_match("/.com\/.*\..*/", $currentPage))
				return getWorkingDirectory($currentPage, 0) . $relativeURL;
			//else 
			//	echo "WOHHHHH";
		}
		
		//case when relative URL has nothing in front of it (e.g., "support/faq.php")
		if($relativeURL[0] != "." and $relativeURL[0] != "/"){
			//first trim off any trailing slash
			//if($localDebug == 1)
			//	echo "(" . strlen($currentPage) . ")<br>";
			if($currentPage[strlen($currentPage) - 1] == "/"){
				$currentPage = substr($currentPage, 0, strlen($currentPage) - 1);
				//if($localDebug == 1)
				//	echo "Stripping trailing slash<br>";	
			}
			
			$tokens = explode("//", $currentPage);
			
			$protocol = $tokens[0] . "//";
			$tokens = explode("/", $tokens[1]);
			//if($localDebug == 1)
			//	echo count($tokens) . " tokens have been found<br>";
			//print_r($tokens);
			//print_r($tokens);
			//if($localDebug == 1)
			//	echo "<br>";
			
			//check to see if the current page is a file (e.g., example.com/help/faq.php) or not (e.g., example.com/help)
			//if so, we need to remove an additional token from $currentPage
			$offset = 0;
			if(strpos($tokens[count($tokens) - 1], ".cfm") or 
			   strpos($tokens[count($tokens) - 1], ".html") or
			   strpos($tokens[count($tokens) - 1], ".php") or 
			   strpos($tokens[count($tokens) - 1], ".htm"))
				$offset = 1;
			
			//if($localDebug == 1)
			//	echo "The offset currently is $offset after looking at " . $tokens[count($tokens) - 1] . "<br>";
			
			
			//now look at the relative link
			//if we have something like 'support/about.php', the offset into the current address should remain as is
			//if we have something like about.php, we don't want the offset to be so high
			if(!strpos($relativeURL, '/') or !strpos($relativeURL, "."))
				$offset -= 1;
			
			if($offset < 0 and count($tokens) == 1)
				$offset = 0;
			
			$currentPage = "";	
			//if there is only one token, it must be included as part of $currentPage
			if((count($tokens) - $offset) == 1){
				//if($localDebug == 1)
				//	echo "Using one token case: " . $tokens[0]  . "<br>";
				$currentPage = $tokens[0] . "/";
			}
	
			//if($localDebug == 1)
				//echo "There are " . count($tokens) . " tokens and an offset of $offset; relative URL is $relativeURL<br>";
			
			//this is the case when there are multiple tokens, some of which might not be included
			for($i = 0; $i < (count($tokens) - 1 - $offset); $i++){
				//if($localDebug == 1)
				//	echo "Looking at token: " . $tokens[$i] . "<br>";
				$currentPage .= $tokens[$i] . "/";
			}

			//if($localDebug == 1)
			//	echo "currentPage = $currentPage and relativeURL = $relativeURL<br>";
			
			//if($localDebug == 1)
			//	echo "Returning " . $protocol . $currentPage . $relativeURL . "<br>";
				
			return $protocol . $currentPage . $relativeURL;
		}
		
		//case when relative URL has some level of "../../";
		$count = substr_count($relativeURL, '../');
		if($count > 0){
			//nuke all of the "../" in the relative URL
			$relativeURL = str_replace("../", '', $relativeURL);
			
			//if($localDebug == 1)
				//echo "Processing a ../ type URL " . getWorkingDirectory($currentPage, $count) . " with count $count<br>";

			//if the end is a folder, we can just go up as normal; if it's a file... we need to remove that, THEN go up
			if(!preg_match("/http:\/\/.*\/.*\..*$/", $currentPage))
				return getWorkingDirectory($currentPage, $count) . $relativeURL;
			else{
					//echo $currentPage . "<br>";
					$currentPage = explode("//", $currentPage);
					$currentPage = explode("/", $currentPage[1]);
					$currentPage[count($currentPage) - 1] = "";
					$currentPage = implode($currentPage, "/");
					$currentPage = "http://" . $currentPage;
					
					//not totally sure why we need +1 here, but it seems to work
					return getWorkingDirectory($currentPage, $count + 1) . $relativeURL;
			}
		}
		
		//case when URL is exactly ".."
		if($relativeURL[0] == "." and $relativeURL[1] == "."){
			$relativeURL = str_replace("..", '', $relativeURL);
			return getWorkingDirectory($currentPage, 1) . $relativeURL;
		}
			
		
		//case when relative URL has "/file"; use ROOT
		if($relativeURL[0] = "/"){
			//strip out the '/'
			//$relativeURL = str_replace("/", '', $relativeURL);
			$relativeURL = substr($relativeURL, 1, 9999);
			
			return getRoot($currentPage) . $relativeURL;
		}
	}
	
	function getRoot($url){
		/**
		 * Returns the root of the specified URL
		 * e.g., http://www.example.com/demo/test -> http://www.example.com
		 * 
		 * @param string $url The URL to resolve
		 * @return string The root of $url
		 */
		$tmp = explode("//", $url);
		$protocol = $tmp[0];
		$tmp = $tmp[1];
		$tmp = explode("/", $tmp);
		
		return $protocol . "//" . $tmp[0] . "/";
	}
	
	function getWorkingDirectory($url, $up){
		/**
		 * Returns the working directory of the URL
		 * e.g., http://www.example.com/files/download.php -> http://www.example.com/files/
		 * 
		 * @param string $url The URL to dissect
		 * @param integer $up The number of levels to go up (e.g., "../../../files" = 3)
		 * @return string The working directory based on $url
		 */
		
		//returns the working directory of the specified (absolute) URL
		$tmp = explode("//", $url);
		$protocol = $tmp[0];
		
		//split the rest of the URL on slashes
		$tmp = explode("/", $tmp[1]);
		
		//print_r($tmp);
		//echo "<br>";
		
		$workingDirectory = '';
		
		//we go 'less than count$tmp) - $up' because we won't want to include the actual file
		//the $up corresponds to a path such as "../../../../file.php"
		for($i = 0; $i < count($tmp) - $up; $i++)
			$workingDirectory .= $tmp[$i] . "/";
			
		//echo "Working directory = $workingDirectory<br>";
			
		//reattach the protocol
		$workingDirectory = $protocol . "//" . $workingDirectory;
		
		//check the last element in tmp; if it's a file, we were right not to include it (contains a '.')
		//but if it was a link to an index file (e.g., http://www.example.com/test) we need the /test part too
			
		//we check for a "." because it indicates a file, but it could also be part of a server name
		//if the count = 1, chances are its part of the name
		//alternately, is there only one token, we should just stick with $workingDirectory
		
		return $workingDirectory;
		
		
		if((count($tmp) > 1 and strstr($tmp[count($tmp) - 1], ".")) or $tmp[count($tmp) - 1] == '' or count($tmp) == 1){
			//echo "Returning #1 $workingDirectory<br>";
			return $workingDirectory;
		}
		else{
			//echo "Returning #2" . $workingDirectory . $tmp[count($tmp) - 1] . "/" . "<br>";
			return $workingDirectory . $tmp[count($tmp) - 1] . "/";
		}
	}
	

	function get_domain($url){
		/**
		 * Returns the domain of the specified URL
		 * e.g., http://support.ucdavis.edu/support/faq.html => http://support.ucdavis.edu
		 * 
		 * @param string $url The URL to extract the domain from
		 * @return string
		 * 
		 */

		$tokens = explode("//", $url);
		$tmp    = explode("/", $tokens[1]);
		
		if(isset($tokens[0]) and $tokens[0] = "http")
			return $tokens[0] . "//" . $tmp[0];
		else 	
			return;
	}

?>